
#include "friend.pb.h"
#include "rpc_channel.h"
#include "rpc_controller.h"

#include <condition_variable>
#include <cstdlib>
#include <future>
#include <google/protobuf/service.h>
#include <iostream>
#include <memory> // 添加智能指针支持
#include <mutex>
#include <thread>
#include <unistd.h> // for usleep
#include <vector>

// 每个线程的任务函数
void callRpcForUser(uint32_t userid, int count, const std::string& ip, short port) {
    // 创建 stub 和 controller
    fixbug::FriendServiceRpc_Stub stub(new MprpcChannel(ip, port, true));
    MprpcController               controller;

    // 创建请求和响应对象
    fixbug::GetFriendsListRequest  request;
    fixbug::GetFriendsListResponse response;

    // 设置请求参数
    request.set_userid(userid);

    // 调用 RPC 方法 count 次
    while (count--) {
        // 随机睡眠 50ms ~ 450ms
        usleep(50000 + rand() % 400000);
        // std::cout << "User " << userid << " 倒数 " << count << " 次发起 RPC 请求" << std::endl;

        // 发起 RPC 调用
        stub.GetFriendsList(&controller, &request, &response, nullptr);

        // 检查调用结果
        if (controller.Failed()) {
            std::cout << "User " << userid << " RPC 调用失败: " << controller.ErrorText() << std::endl;
        } else {
            if (0 == response.result().errcode()) {
                int size = response.friends_size();
                std::cout << "User " << userid << " 收到回应共 " << response.ByteSizeLong()
                          << " Bytes, 好友数量: " << size << std::endl;
            } else {
                std::cout << "User " << userid << " RPC 业务逻辑失败: " << response.result().errmsg() << std::endl;
            }
        }
    }
}

void callAsyncRpcForUser(uint32_t userid, int count, const std::string& ip, short port) {
    // 创建 stub 和 controller
    MprpcChannel                  channel(ip, port, true); // connectNow = true
    fixbug::FriendServiceRpc_Stub stub(&channel);

    // 调用 RPC 方法 count 次
    while (count--) {
        // 随机睡眠 50ms ~ 450ms
        usleep(50000 + rand() % 400000);
        auto* controller = new MprpcController();
        // 创建请求和响应对象
        auto* request  = new fixbug::GetFriendsListRequest();
        auto* response = new fixbug::GetFriendsListResponse();

        // 设置请求参数
        request->set_userid(userid);

        // std::cout<<"[异步] User " << userid << " 发起 RPC 请求" << std::endl;
        stub.AsyncGetFriendsList(controller, request, response, nullptr);
        // stub.GetFriendsList(controller, request, response, nullptr);

        // std::this_thread::sleep_for(std::chrono::seconds(3));
        // 响应处理应该在这里
        if (controller->Failed()) {
            std::cout << "[异步] User " << userid << " 失败: " << controller->ErrorText() << std::endl;
        } else {
            if (0 == response->result().errcode()) {
                int size = response->friends_size();
                std::cout << "[异步] User " << request->userid() << " 收到响应: " << size << " 好友" << std::endl;
                for (int i = 0; i < size; ++i) {
                    std::cout << response->friends(i) << " ";
                }
                std::cout << std::endl;
            } else {
                std::cout << "[异步] User " << request->userid() << " 业务逻辑失败: " << response->result().errmsg()
                          << std::endl;
            }
        }
        // 处理完成后删除对象
        // delete callback;
        delete controller;
        delete request;
        delete response;
    }
}

int main(int argc, char** argv) {
    std::string ip   = "127.0.1.1";
    short       port = 7788;

    int user_count = 10; // 用户数量
    int rpc_count  = 1;  // 每个用户调用 RPC 的次数

    // 创建线程池
    std::vector<std::thread> threads;

    // std::cout << "开始进行同步RPC测试" << std::endl;
    // // 为每个用户创建一个线程
    // for (uint32_t userid = 1000; userid < 1000 + user_count; ++userid) {
    //     threads.emplace_back(callRpcForUser, userid, rpc_count, ip, port);
    // }

    // // 等待所有线程完成
    // for (auto& thread : threads) {
    //     thread.join();
    // }
    std::cout << "开始进行异步RPC测试" << std::endl;
    // 为每个用户创建一个线程
    for (uint32_t userid = 1000; userid < 1000 + user_count; ++userid) {
        threads.emplace_back(callAsyncRpcForUser, userid, rpc_count, ip, port);
    }

    // 等待所有线程完成
    for (auto& thread : threads) {
        thread.join();
    }

    std::cout << "所有用户的 RPC 调用已完成！" << std::endl;

    return 0;
}
